home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / os2tools / hos20001 / revisor.asm < prev   
Assembly Source File  |  1990-03-26  |  30KB  |  1,106 lines

  1.     .MODEL   small,pascal
  2.     TITLE Resolver Source Control Aid
  3.     PAGE    60,124
  4.     .286
  5.  
  6.  
  7. Comment   *
  8.     Assembler Version Of OS/2 Revisor Hack Code.
  9.     00:09:55    18-Mar-1990
  10.     Frank V. Castellucci
  11.     RR1 265 Overlook Way
  12.     Purdys, NY 10578
  13.     ( 914 ) 277-4312
  14.     *
  15.  
  16. Comment *
  17.     01:13:38 21-Mar-1990
  18.     Changes include fix to retrieve file size of alternate input as
  19.     opposed to key input. This way the project name identifier will
  20.     not be the input to the file data offset indicator.
  21.     *
  22. Comment *
  23.     21:49:55    26-Mar-1990
  24.     Completed port to assembler.
  25.     Additional capabilities include the DUMP and LIST switch.
  26.     Have changed the construct of the TOKEN structure to include
  27.     an alternate name and alternate flag.
  28.     Although new this should still work with any older versions because
  29.     the structure size did not change, just reduced the filename size
  30.     and used the remainder to store an alternate name.
  31.     *
  32.  
  33. ;******************************************************************
  34. ; Common Structures And Equates
  35. ;******************************************************************
  36.  
  37. ; General Usage
  38. MY_MESSGS    EQU 0009h    ; Number Of Text Messages
  39. INFO_MESSGS    EQU 0003h    ; Number Of Description Text Lines
  40.  
  41. LISTINFO    EQU 0001h    ; Switch 'LIST' flag
  42. LISTALTI    EQU 0100h    ; Switch 'LIST ALTERNATE' flag
  43. LISTDATA        EQU LISTINFO OR LISTALTI
  44.  
  45. DUMPINFO    EQU 0002h    ; Switch 'DUMP' flag
  46. BADSWITCH    EQU -1        ; Switch Unknown flag
  47.  
  48. LISTCALL    EQU 0000h    ; Routine Flags
  49. DUMPCALL        EQU 0001h
  50.  
  51. ; For File Routines
  52.  
  53. FILE_BEGIN    EQU    0000h    ; For Changing File pointers
  54. FILE_CURRENT    EQU    0001h    ; From current or unknown
  55. FILE_END    EQU    0002h    ; positions
  56.  
  57. ; Directory handle types
  58.  
  59. HDIR_SYSTEM    EQU    0001h    ; System File Find Handle
  60. HDIR_CREATE    EQU    -1    ; Flag to create your own
  61.  
  62. ; Dosopen/DosQFHandState file attributes
  63.  
  64. FILE_NORMAL    EQU    0000h    ; Flags for opening files as read
  65. FILE_READONLY    EQU    0001h
  66. FILE_HIDDEN    EQU    0002h
  67. FILE_SYSTEM    EQU    0004h
  68. FILE_DIRECTORY    EQU    0010h
  69. FILE_ARCHIVED    EQU    0020h
  70.  
  71. ; DosOpen() open flags
  72.  
  73. FILE_OPEN    EQU    0001h    ; How to open the files
  74. FILE_TRUNCATE    EQU    0002h
  75. FILE_CREATE    EQU    0010h
  76.  
  77.  
  78. ; DosOpen() actions
  79.  
  80. FILE_EXISTED    EQU    0001h    ; Return Actions By OS/2
  81. FILE_CREATED    EQU    0002h
  82. FILE_TRUNCATED    EQU    0003h
  83.  
  84. ; DosOpen/DosSetFHandState flags
  85.  
  86. OPEN_ACCESS_READONLY    EQU    0000h        ; Access and sharing flags
  87. OPEN_ACCESS_WRITEONLY    EQU    0001h
  88. OPEN_ACCESS_READWRITE    EQU    0002h
  89. OPEN_SHARE_DENYREADWRITE EQU    0010h
  90. OPEN_SHARE_DENYWRITE    EQU    0020h
  91. OPEN_SHARE_DENYREAD    EQU    0030h
  92. OPEN_SHARE_DENYNONE    EQU    0040h
  93. OPEN_FLAGS_NOINHERIT    EQU    0080h
  94. OPEN_FLAGS_FAIL_ON_ERROR EQU    2000h
  95. OPEN_FLAGS_WRITE_THROUGH EQU    4000h
  96. OPEN_FLAGS_DASD      EQU    8000h
  97.  
  98. ; Flag Equate For Extracting Date and Time Values From Word Variable
  99.  
  100. DDAY        EQU     0000000000011111b
  101. DMON        EQU     0000000111100000b
  102. DYRS        EQU     1111111000000000b
  103.  
  104. MONSHFT     EQU    5
  105. YRSHFT        EQU    MONSHFT + 4
  106.  
  107. TSEC        EQU     0000000000011111b
  108. TMIN        EQU     0000011111100000b
  109. THRS        EQU     1111100000000000b
  110.  
  111. MINSHFT     EQU    5
  112. HRSHFT        EQU    MINSHFT + 6
  113.  
  114. ; File time and date types for DosFindFirst
  115. FTIME   struc
  116. ftime_fs    dw    ?
  117. FTIME   ends
  118.  
  119. FDATE   struc
  120. fdate_fs    dw    ?
  121. FDATE     ends
  122.  
  123. ; Directory structure for DosFindFirst
  124.  
  125. FILEFINDBUF struc
  126. findbuf_fdateCreation    dw    (size FDATE)/2 dup (?)
  127. findbuf_ftimeCreation    dw    (size FTIME)/2 dup (?)
  128. findbuf_fdateLastAccess dw    (size FDATE)/2 dup (?)
  129. findbuf_ftimeLastAccess dw    (size FTIME)/2 dup (?)
  130. findbuf_fdateLastWrite    dw    (size FDATE)/2 dup (?)
  131. findbuf_ftimeLastWrite    dw    (size FTIME)/2 dup (?)
  132. findbuf_cbFile        dd    ?
  133. findbuf_cbFileAlloc    dd    ?
  134. findbuf_attrFile    dw    ?
  135. findbuf_cchName     db    ?
  136. indbuf_achName        db    13 dup (?)
  137. FILEFINDBUF ends
  138.  
  139. REVTOKEN struc
  140. FileName    db    32 DUP(?)
  141. AltFlag     dw    ?
  142. AltName     db    94 DUP(?)
  143. DStamp        dw    (size FDATE)/2 dup (?)
  144. TStamp        dw    (size FTIME)/2 dup (?)
  145. Sig        dd    ?
  146. ByteDesc    dd    ?
  147. REVTOKEN ends
  148.  
  149. SCREENREC struc
  150. KeyName     db    'Key Name or Alternate Key Name  '
  151.         db    5 DUP(20h)    ; Used For Alternate Key As Well
  152. DateStmp    db    'DateStmp'    ; Date Stamp
  153.         db    5 DUP(20h)    ; Filler Space
  154. TimeStmp    db    'TimeStmp'    ; Time Stamp
  155.         db    5 DUP(20h)    ; Filler
  156. FSizeB        db    'Size '     ; Size Of File
  157.         db    5 DUP(20h)    ; Filler Space
  158. SigNat        db    4 DUP(20h)    ; My Signature
  159. CrLf        db    0dh,0ah     ; EOL
  160. SCREENREC ends
  161.  
  162. SCRNLINE    EQU    SIZE SCREENREC
  163. SCRNDATA    EQU    SIZE SCREENREC.CrLf - SCRNLINE
  164.  
  165. ;******************************************************************
  166. ; Macro For Easy Reading
  167. ;******************************************************************
  168.  
  169. ; @ArgvArgc prepares a call to the ArgvArgc function
  170.  
  171. @ArgvArgc MACRO argS1,argO1,argO2
  172.     push    argS1
  173.     push    argO1
  174.     push    argO2
  175.     call    ArgvArgc
  176.     ENDM
  177.  
  178. ; @FStrMove prepares a call to the FStrMove function
  179.  
  180. @FStrMove MACRO argS1,argO1,argS2,argO2
  181.     push    argS1
  182.     push    argO1
  183.     push    argS2
  184.     push    argO2
  185.     call    FStrMove
  186.     ENDM
  187.  
  188. ; @VioWrtTTY    prepares a call to the VioWrtTTY function
  189.  
  190. @VioWrtTTY MACRO argS1,argO1,argLen,hvio
  191.     push    argS1
  192.     push    argO1
  193.     push    argLen
  194.     push    hvio
  195.     call    VioWrtTTY
  196.     ENDM
  197.  
  198. ; This macro clears the video buffer with blanks
  199.  
  200. CLRBUFF MACRO argL1
  201.     push    bx
  202.     push    cx
  203.     mov    bx,offset argL1
  204.     mov    cx,SCRNDATA
  205. @@:    mov    BYTE PTR [bx],20h
  206.     inc    bx
  207.     loop    @B
  208.     pop    cx
  209.     pop    bx
  210.     ENDM
  211.  
  212. ; This multiplies Factor by Multiplier and puts result in Results
  213. ; also saves contents of the BX register
  214.  
  215. CALCARRAYOFF    MACRO     Results,Factor,Multiplier
  216.     push    bx
  217.     mov    bx,offset Factor
  218.     imul    Results,[bx],size Multiplier
  219.     pop    bx
  220.     ENDM
  221.  
  222. ; This macro tests the character to see if it is in upper case, if not
  223. ; it converts it, if so it jumps to the closest local forward label
  224.  
  225. UPPERCASE MACRO accumb
  226.     cmp    accumb,60h
  227.     jl    @F
  228.     sub    accumb,20h
  229.     ENDM
  230.  
  231. ; Extraction Macros For Screen Display
  232.  
  233. XDAY    MACRO argIn
  234.     and    argIn,DDAY
  235.     ENDM
  236.  
  237. XMON    MACRO argIn
  238.     and    argIn,DMON
  239.     shr    argIn,MONSHFT
  240.     ENDM
  241.  
  242. XYRS    MACRO argIn
  243.     and    argIn,DYRS
  244.     shr    argIn,YRSHFT
  245.     add    argIn,80
  246.     ENDM
  247.  
  248. XSEC    MACRO argIn
  249.     and    argIn,TSEC
  250.     shl    argIn,1
  251.     ENDM
  252.  
  253. XMIN    MACRO argIn
  254.     and    argIn,TMIN
  255.     shr    argIn,MINSHFT
  256.     ENDM
  257.  
  258. XHRS    MACRO argIn
  259.     and    argIn,THRS
  260.     shr    argIn,HRSHFT
  261.     ENDM
  262.  
  263. ;******************************************************************
  264. ; Simplified MASM Segments
  265. ; STACK is 4k
  266. ; DATA holds initialized and uninitialized variables
  267. ; CONST holds strings as they wont change through the app
  268. ;******************************************************************
  269.  
  270.     .STACK    4096
  271.  
  272.     .CONST
  273. Err0    db   'Invalid Parms: Usage = REVISOR Keyfile.ext Cat.rev Inp.ext',0dh,0ah
  274. Erl0    EQU    $-Err0
  275. Err1    db   '                           or  KeyFile.ext , Inp.ext',0dh,0ah
  276. Erl1    EQU    $-Err1
  277. Err2    db   '                           or  KeyFile.ext Cat.rev',0dh,0ah
  278. Erl2    EQU    $-Err2
  279. Err3    db   '                           or  KeyFile.ext ',0dh,0ah
  280. Erl3    EQU    $-Err3
  281. Err4    db   'Invalid KeyFile Name',0dh,0ah
  282. Erl4    EQU    $-Err4
  283. Err5    db   'No Input File Found For Revision Storage',0dh,0ah
  284. Erl5    EQU    $-Err5
  285. Err6    db   'Switch Usage: REVISOR Keyfile.ext -L  List Cat Key Info',0dh,0ah
  286. Erl6    EQU    $-Err6
  287. Err7    db   '                   or -D Cat.rev      List All Keys Info',0dh,0ah
  288. Erl7    EQU    $-Err7
  289. Err8    db   'Catalog File Existense Error!',0dh,0ah
  290. Erl8    EQU    $-Err8
  291.  
  292.         .DATA
  293. CommandArgC    dw    ?        ; Command Line Argument Count
  294. CommandArgv    dw    16 DUP(?)    ; OffSet To Command Line
  295. CommandSel    dw    ?        ; Selector To Above Segment
  296. hdir        dw    ?
  297. hfCatalog    dw    ?        ; File Handles
  298. hfAltInput    dw    ?
  299. Newlocation    dd    ?
  300. fFind        FILEFINDBUF 3 DUP(<>)    ; FileFindFirst Structure Array
  301. Header        REVTOKEN    <>    ; Token Structure For Scans
  302. MainLine    SCREENREC    <>    ; Screen Record Line
  303. SeprLine    SCREENREC    <"--------------------------------",,\
  304.                  "--------",,"--------",,"-----",,,>
  305. AltLine     SCREENREC    <>    ; Alternate Record Line
  306. DataBuff    db    8192    DUP(?)    ; Data Transfer Local Buffer
  307.  
  308.  
  309. InfoCount    dw    0          ; File Find Counter
  310. InfoFlag    dw    0
  311. SwitchFlag    dw    2 DUP(0)
  312. SwitchPos    dw    0
  313.                 ; Stringlength Arrays
  314. cbError     dw    Erl0,Erl1,Erl2,Erl3,Erl4,Erl5,Erl6,Erl7,Erl8
  315.                 ; Array Of String Pointers
  316. pszErrs     dw    Err0,Err1,Err2,Err3,Err4,Err5,Err6,Err7,Err8
  317.  
  318. Token        REVTOKEN <,0,,,,434a5646h,>    ; Token Structure For General
  319.  
  320.  
  321.     ; revisor.lst
  322.     .CODE
  323.     ; External Interfaces to OS/2 functions
  324.  
  325.     EXTRN VioWrtTTY:FAR,DosFindFirst:FAR,DosFindClose:FAR
  326.     EXTRN DosChgFilePtr:FAR, DosOpen:FAR, DosRead:FAR, DosWrite:FAR
  327.     EXTRN DosClose:FAR, DosExit:FAR
  328.  
  329. Revisor PROC    FAR
  330.     mov    CommandSel,ax        ; Save Selector And Offset
  331.     mov    dx,offset CommandArgv    ; Address Table Of Commands
  332.     @ArgvArgc ax,bx,dx        ; Parse Command Line
  333.  
  334. NormalScanDone:
  335.     mov    dx,CommandArgC
  336.     cmp    dx,0000h    ; Test Argument Counter
  337.     jnz    @F        ; If we have any arguments
  338.     mov    cx,4
  339.     xor    bx,bx
  340.     jmp    ErrorOut1    ; Otherwise Display And Exit
  341.     ;
  342. @@:    mov    es,CommandSel    ; Load Extra Segment
  343.     mov    cx,dx        ; Get Parameter Count
  344.     mov    dx,0001     ; Now Our Index For Switch Work
  345.     xor    bx,bx        ; Get Pointer Setup
  346.     cmp    cx,2        ; Switch Concern 1 and 2 position
  347.     jng    Nscn0        ;
  348.     dec    cx        ; Only Test First 2
  349.     ;
  350. Nscn0:                ; Normal Switch Text
  351.     shl    bx,1        ; Into Command Line
  352.     mov    di,CommandArgv[bx]
  353.     call    SpecialSwitch    ; Test If Switch
  354.     or    ax,ax        ; Compare Results
  355.     jz    @F        ; No Switch
  356.     mov    SwitchPos,dx    ; Save Argument Index
  357.     mov    SwitchFlag[bx],ax    ; Save Value
  358. @@:    inc    dx        ; Next Arg Flag Identifier
  359.     inc    bx        ; Next ArgV
  360.     loop    Nscn0        ; Loop Normal Switch
  361.     ;
  362.     cmp    SwitchPos,0    ; If No Switches
  363.     jz    DoGetCat    ; Get Catalog Information
  364.     cmp    SwitchPos,2    ; Or if List Switch
  365.     jnz    @F        ; Or forget it as we have alternative
  366.         ;
  367. DoGetCat:
  368.     or    InfoFlag,1    ; First Check To See If Cat Exists
  369.     push    es        ; And Also Convert Name In Process
  370.     push    CommandArgv[0]    ; Check For First File
  371.     call    RevGetFileData    ; Check Base Existense
  372.     ;
  373.     push    es        ; And Also Convert Name In Process
  374.     push    CommandArgv[0]
  375.     call    CheckCatalog
  376.     or    InfoFlag,ax    ; Results Determine Alternate Usage
  377.     ;
  378. @@:    cmp    SwitchPos,0    ; Check if normal ops again
  379.     jz    NoSwitchRoutine ; If So then continue verification
  380.     jmp    HaveSwitch    ; Have A Switch
  381. NoSwitchRoutine:        ; Otherwise Stuff Revision In Catalog
  382.     cmp    CommandArgC,0002h    ; Do We Have Reason To Test Else?
  383.     jl    NoAltCat        ; Nope Straight Talk
  384.     mov    di,CommandArgv[0002]    ; Marked for default catalog usage
  385.     cmp    BYTE PTR es:[di],','
  386.     jz    TestAltInpt        ; Default Cat check Alternate Input
  387.     xor    InfoFlag,0002h        ; Flip Flag Defualt Cat Off
  388.     cmp    InfoCount,1        ; Reuse FindFileStructure
  389.     jle    @F
  390.     dec    InfoCount        ; Reuse FileFindStructure From Default
  391. @@:    or    InfoFlag,0004h        ; Flag Alternate Used
  392.     push    es
  393.     push    di
  394.     call    RevGetFileData        ; Check Alt Existense
  395.     or    ax,ax
  396.     jz    TestAltInpt
  397.     or    InfoFlag,0020h        ; If Alt Not Exist then Create
  398. TestAltInpt:
  399.     cmp    CommandArgC,3        ; Alternate Input Source?
  400.     jl    NoAltCat        ; If not then skip routine
  401.     mov    di,CommandArgv[0004]    ; Alt Name Pointer Offset
  402.     push    es
  403.     push    di
  404.     call    RevGetFileData        ; Check Alt Existense
  405.     or    ax,ax            ; From Return Code
  406.     jz    @F            ; If Exists
  407.     mov    cx,1            ; Flag Dependant File Error
  408.     mov    bx,5
  409.     shl    bx,1
  410.     jmp    ErrorOut1
  411. @@:    or    InfoFlag,0008h        ; Flag Alternate Input File
  412.     mov    Token.AltFlag,1
  413.     mov    bx, offset Token.AltName
  414.     @FStrMove es,di,ds,bx        ; Make Call
  415.     ;
  416. NoAltCat:
  417.     mov    bx,offset fFind     ; Get Target File Size In Bytes
  418.     cmp    CommandArgC,3        ; See if we need alt input size
  419.     jl    @F            ; If Not Take Key Data
  420.     dec    InfoCount        ; Adjust for Zero Offset to counter
  421.     CALCARRAYOFF    ax,InfoCount,<FILEFINDBUF>
  422.     inc    InfoCount        ; Reset for possible reuse
  423.     add    bx,ax            ; Add Offset To Alt Input Information
  424. @@:                    ; Provide information in token
  425.     mov    di,offset Token
  426.     mov    ax,WORD PTR [bx].findbuf_cbFile
  427.     mov    cx,WORD PTR [bx].findbuf_cbFile+2
  428.     mov    WORD PTR [di].ByteDesc,ax
  429.     mov    WORD PTR [di].ByteDesc+2,cx
  430.     mov    ax,[bx].findbuf_fdateLastWrite
  431.     mov    cx,[bx].findbuf_ftimeLastWrite
  432.     mov    [di].DStamp,ax
  433.     mov    [di].TStamp,cx
  434.     call    AddChangeInfo
  435.     jmp    NormalOut
  436.  
  437. HaveSwitch:
  438.     mov    bx,SwitchPos        ; Where is switch
  439.     dec    bx
  440.     shl    bx,1            ; Offset Zero Into Results Array
  441.     mov    ax,SwitchFlag[bx]    ; Load For Other Testing
  442.     test    ax,BADSWITCH        ; Bad Switch
  443.     jnz    @F            ; Good Switch
  444. BadSyntax:
  445.     mov    cx,2            ; Display Bad Switch Error
  446.     mov    bx,6            ; This Line
  447.     shl    bx,1            ; Word Offset
  448.     jmp     short ErrorOut1         ; Bad Switch Passed
  449. @@:    mov    bx,ax
  450.     and    bx,LISTDATA        ; Test For Explicit List Command
  451.     jnz    @F
  452.     jmp    short tDump
  453. @@:    mov    cx,ax
  454.     cmp    CommandArgC,2        ; Better Be At In First Position
  455.     jl    BadSyntax        ; If Not Then Flag Error
  456.     cmp    CommandArgC,3        ; Test For Alternate Rev Library
  457.     jl    @F
  458.     xor    InfoFlag,0002h
  459.     dec    InfoCount
  460.     mov    bx,4            ; OffSet To Third Argument
  461.     mov    bx,CommandArgv[bx]    ; Get Alt Rev Arg
  462.     push    es            ; Push Zero Terminated String
  463.     push    bx
  464.     call    RevGetFileData        ; Check File Is Alive
  465.     or    ax,ax            ; If Good Continue
  466.     jz    @F
  467.     jmp    short BadSyntax     ; Else Error Correct
  468. @@:    push    cx
  469.     call    RevListKeyInfo        ; Make Usefull Call
  470.     jmp    short SwitchDone    ; Exit Application
  471.  
  472. tDump:
  473.     cmp    ax,DUMPINFO        ; Test For Implied Dump
  474.     jz    @F
  475.     jmp    BadSyntax        ; Error Or New Switch Jump Goes Here
  476. @@:
  477.     cmp    CommandArgC,2        ; If DUMP ok then check parm count
  478.     jz    tDump1            ; For Cat Name exclusive
  479.     jmp    BadSyntax        ; If No Catalog Specified
  480.                     ; Later hacks can use wild cards for
  481.                     ; all .REV extension listings
  482. tDump1:
  483.     mov    cx,ax
  484.     mov    bx,2            ; OffSet To Second Argument Cat Name
  485.     mov    bx,CommandArgv[bx]    ; Get Alt Rev Arg
  486.     push    es            ; Push Zero Terminated String
  487.     push    bx
  488.     call    RevGetFileData        ; Check File Is Alive
  489.     or    ax,ax            ; If Good Continue
  490.     jz    @F
  491.     jmp    BadSyntax        ; Else Error Correct
  492. @@:    push    cx
  493.     call    RevDumpKeyInfo
  494.  
  495. SwitchDone:
  496.  
  497.     jmp     short NormalOut
  498.  
  499. ErrorOut1:                ; No Command Line Information
  500. @@:    push    ds            ; Push Pointer To String
  501.     push    offset pszErrs[bx]
  502.     push    cbError[bx]        ; Push String Length
  503.     push    0000h            ; Handle To Vio always 0
  504.     call    VioWrtTTY
  505.     add    bx,2            ; Next Group
  506.     loop    @B
  507.     mov    ax,1            ; Return Code To OS/2 CMD = 1
  508.  
  509. NormalOut:                ; Single Exit Point For Entire App
  510.     push    1            ; End Entire Process
  511.     push    ax            ; And Return Code
  512.     call    DosExit
  513. Revisor ENDP
  514.  
  515. AddChangeInfo PROC    NEAR    USES ES DI SI
  516.     mov    dx,1
  517.     test    InfoFlag,0002h        ; Test If Default Cat Used
  518.     jz    UseAlt
  519.     test    InfoFlag,0010h        ; Test If We Must Create It
  520.     jz    @F
  521.     or    dx,0002h        ; If So Then Flag = 3
  522. @@:    mov    ax,ds            ; Get Local Default Name
  523.     mov    es,ax
  524.     mov    di,offset Token     ; And FileName = Key Pointer
  525.     jmp    short OpenCat        ; Open The Catalog
  526. UseAlt:
  527.     test    InfoFlag,0020h        ; Test If Creation on Alt Required
  528.     jz    @F
  529.     or    dx,0002h        ; Flag Creation Of File
  530. @@:    mov    es,CommandSel
  531.     mov    di,CommandArgv[0002]    ; Pointer To Command Line Arg
  532. OpenCat:
  533.     push    dx            ; Push Flag
  534.     push    es
  535.     push    di            ; Pointer To File Name
  536.     push    ds
  537.     push    offset hfCatalog
  538.     call    DoOpenFile        ; Call Routine
  539.  
  540.     or    ax,ax            ; Open Error?
  541.     jnz    BadOpen
  542.     mov    es,CommandSel        ; Point To Command Line
  543.     mov    di,CommandArgv[0000]    ; First Argument Assumption
  544.     mov    bx,offset Token
  545. KeyMove:
  546.     mov    al,BYTE PTR es:[di]    ; Move File Name Into Token
  547.     cmp    al,00h
  548.     jz    @F
  549.     mov    BYTE PTR [bx],al
  550.     inc    bx
  551.     inc    di
  552.     jmp    short KeyMove
  553.  
  554. @@:    mov    BYTE PTR [bx],al
  555.     mov    di,CommandArgv[0000]    ; Find Alt or Current Input
  556.     mov    dx,0005h
  557.     push    dx
  558.     push    es
  559.     cmp    CommandArgC,3
  560.     jl    @F
  561.     mov    di,CommandArgv[0004]
  562. @@:    push    di
  563.     push    ds
  564.     push    offset hfAltInput
  565.     call    DoOpenFile        ; Open File For Input
  566.     or    ax,ax
  567.     jnz    BadOpen
  568.     push    hfCatalog
  569.     push    hfAltInput
  570.     call    MoveRevision        ; Move The Data Into Repository
  571.     xor    ax,ax
  572. BadOpen:
  573.     ret
  574. AddChangeInfo ENDP
  575.  
  576. MoveRevision PROC USES SI DI,hfileD:WORD, hfileS:WORD
  577.     push    hfileD
  578.     push    ds
  579.     push    offset Token
  580.     push    size REVTOKEN
  581.     call    DoWriteData
  582. MoveData:
  583.     push    hfileS            ; Push Source File Handle
  584.     push    ds
  585.     mov    bx,offset DataBuff    ; Pointer To Data Buffer
  586.     push    bx
  587.     push    8192            ; Size Of Buffer To Fill
  588.     call    DoReadData        ; Read The Data
  589.     or    ax,ax            ; Any Data Left
  590.     jz    Done            ; Nope, all done with transfer
  591.     push    hfileD            ; Push Repository Handle
  592.     push    ds
  593.     mov    bx,offset DataBuff    ; Pointer To Data Buffer
  594.     push    bx
  595.     push    ax            ; Data Size Returned From Read
  596.     call    DoWriteData        ; Commit Data to disk
  597.     jmp    short MoveData        ; Loop Up to Top
  598. Done:
  599.     ret
  600. MoveRevision    ENDP
  601.  
  602. CheckCatalog    PROC    NEAR    USES ES DI SI,pszArg:FAR PTR
  603.     les    di,pszArg        ; Load Key Pointer
  604. Ucase:                    ; Make Upper Case
  605.     cmp    BYTE PTR es:[di],00h
  606.     jz        EOL
  607.     UPPERCASE <BYTE PTR es:[di]>
  608. @@:    inc    di
  609.     jmp    short Ucase
  610. EOL:
  611.     les    di,pszArg        ; Reload Pointer
  612.     mov    bx,offset Token     ; Address Structure
  613.     xor    si,si
  614. @@:    mov    al,BYTE PTR es:[di]    ; Transfer Base Key Or FileName
  615.     cmp    al,'.'
  616.     jz    @F
  617.     mov    BYTE PTR [bx][si],al
  618.     inc    di
  619.     inc    si
  620.     jmp    short @B
  621. @@: mov     BYTE PTR [bx][si],al    ; Append Default Catalog Extension
  622.     inc    si
  623.     mov    BYTE PTR [bx][si],'R'
  624.     inc    si
  625.     mov    BYTE PTR [bx][si],'E'
  626.     inc    si
  627.     mov    BYTE PTR [bx][si],'V'
  628.     inc    si
  629.     mov    BYTE PTR [bx][si],00h
  630.  
  631.     push    ds            ; Check For Catalog Exist
  632.     push    bx
  633.     call    RevGetFileData
  634.     or    ax,ax            ; Create Neccessary
  635.     jz    Done
  636.     dec    InfoCount
  637.     or    InfoFlag,0010h
  638.     mov    ax,0002h
  639. Done:
  640.     or    ax,0002h
  641. Done1:
  642.     ret
  643. CheckCatalog    ENDP
  644.  
  645. RevDumpKeyInfo    PROC    NEAR USES DS SI DI, SpecFlag:WORD
  646.     push    0005h            ; We Open The Catalog
  647.     push    CommandSel
  648.     push    CommandArgv[0002]    ; With The Name On Command Line
  649.     push    ds
  650.     push    offset hfCatalog
  651.     call    DoOpenFile        ; Open File
  652.     or        ax,ax        ; If all is well then call list routine
  653.     jnz    DumpError
  654.  
  655.     push    hfCatalog        ; Handle To Cat
  656.     push    SpecFlag        ; Type Call
  657.     call    RevPostInfo        ; Here is where we show what we got
  658.  
  659.     push    hfCatalog        ; On return we close catalog handle
  660.     call    DosClose
  661.  
  662.     xor    ax,ax            ; Return Success Code
  663.  
  664. DumpError:
  665.     ret
  666. RevDumpKeyInfo    ENDP
  667.  
  668. RevListKeyInfo    PROC    NEAR    SpecFlag:WORD
  669.     push    0005h            ; We Open The Catalog
  670.     cmp    CommandArgC,3
  671.     jnz    @F
  672.     push    CommandSel
  673.     push    CommandArgv[0004]    ; Get Alt Rev Arg
  674.     jmp    short OpenCat1
  675. @@:    push    ds
  676.     push    offset Token        ; Or Get Default Based On Key Name
  677. OpenCat1:
  678.     push    ds
  679.     lea    ax,hfCatalog
  680.     push    ax
  681.     call    DoOpenFile        ; Open File
  682.     or        ax,ax        ; If all is well then call list routine
  683.     jnz    ListError
  684.     push    hfCatalog        ; Handle To Cat
  685.     push    SpecFlag        ; Type Call
  686.     call    RevPostInfo        ; Here is where we show what we got
  687.  
  688.     push    hfCatalog        ; On return we close catalog handle
  689.     call    DosClose
  690.     xor    ax,ax            ; Return Success Code
  691. ListError:
  692.     ret
  693. RevListKeyInfo    ENDP
  694.  
  695. RevPostInfo  PROC NEAR \
  696.     USES ES DI SI, hcatFile:WORD,KeyScan:WORD
  697.  
  698.     mov    bx,offset AltLine    ; Point To Data Line
  699.     CLRBUFF AltLine         ; Clear Buffer For Screen
  700.     @VioWrtTTY  ds,bx,SCRNLINE,0    ; Call The Big Guy For Blank Line
  701.  
  702.     mov    bx,offset MainLine    ; Point To Data Line
  703.     @VioWrtTTY  ds,bx,SCRNLINE,0    ; Call The Big Guy For Topic Headers
  704.     mov    bx,offset SeprLine    ; And a dashed seperator line
  705.     @VioWrtTTY  ds,bx,SCRNLINE,0    ; Call The Big Guy For Dashed Line
  706.  
  707. Top0:
  708.     push    hcatFile        ; Push Handle To Catalog and
  709.     push    ds            ; Use the Header Structure as a
  710.     push    offset Header        ; Buffer To return the header info
  711.     push    size REVTOKEN        ; To test for keyname matches
  712.     call    DoReadData
  713.     or    ax,ax            ; Test for EOF
  714.     jnz    @F            ; Have Data
  715.     jmp    short RevOut        ; All Done
  716. @@:    test    KeyScan,2
  717.     jnz    ShowInfo        ; If KeyScan 1 then this is dump info
  718.     mov    bx,offset Header.FileName ; Compare Value Here With Keyname
  719.     push    bx            ; Entered At Command Line
  720.     call    RevC_and_D
  721.     or    ax,ax            ; 0 if match or n for no match
  722.     jz    short ShowInfo        ; Also n=character after no match
  723.     cmp    [bx].AltFlag,0000h    ; If No Alternate Found
  724.     jz    @F            ; Skip Routine
  725.     lea    bx,[bx].AltName     ; Otherwise Load AltName For Comp
  726.     push    bx
  727.     call    RevC_and_D        ; Compare And Display
  728.     or    ax,ax            ; 0 if match or n for no match
  729.     jnz    @F
  730.  
  731. ShowInfo:
  732.     push    ds
  733.     push    offset Header
  734.     push    KeyScan
  735.     call    RevDisplayKey        ; Display Routine
  736. @@:    push    hcatFile        ; Reset File Pointer To After Data
  737.     mov    ax,WORD PTR Header.ByteDesc+2
  738.     push    ax            ; In this variable which is the size
  739.     mov    ax,WORD PTR Header.ByteDesc
  740.     push    ax            ; Of the data when entered into the
  741.     push    FILE_CURRENT        ; catalog. Also if compression is ever
  742.     push    ds            ; implimented this will represent the
  743.     push    offset Newlocation    ; Size of the compressed data.
  744.     call    DosChgFilePtr        ; Change file position and read more
  745.     jmp    Top0
  746. RevOut:
  747.     ret
  748. RevPostInfo  ENDP
  749.  
  750. RevDisplayKey PROC NEAR \
  751.     USES ES DI SI, pTok:FAR PTR, KeyFlag:WORD
  752.  
  753.     mov    bx,offset MainLine    ; Point To Data Line
  754.     CLRBUFF MainLine        ; Clear Buffer For Screen
  755.     @VioWrtTTY  ds,bx,SCRNLINE,0    ; Call The Big Guy For Blank Line
  756.     les    di,pTok         ; Point To Data Structure
  757.     @FStrMove es,di,ds,bx        ; Get Key Name
  758.     xor    dx,dx
  759. RevD0:
  760.     mov    dx,bx
  761.     mov    si,bx
  762. @@:    cmp    BYTE PTR [si],00h    ; Strip Zero Terminate
  763.     jz    @F
  764.     inc    si
  765.     jmp    short @B
  766. @@:    mov    BYTE PTR [si],20h    ; Replace With Blank
  767.     cmp    es:[di].AltFlag,0000h    ; Check For Key Value
  768.     jz    @F            ; If Not Show Data
  769.     jmp    ShowLine        ; Otherwise Just Show Key
  770. @@:    mov    ax,es:[di].DStamp    ; Get Date
  771.     lea    bx,[bx].DateStmp    ; Address Screen Date Pointer
  772.     mov    cx,ax            ; Copy Original
  773.     XMON    ax            ; Extract Month of Year
  774.     push    ax
  775.     push    2
  776.     push    bx
  777.     call    ConvertWrdToAscii    ; Change to ASCII
  778.     add    bx,ax            ; Add Difference From Starting
  779.     mov    BYTE PTR [bx],'/'    ; Put In Seperator
  780.     inc    bx            ; Point To Next Location
  781.     mov    ax,cx            ; Copy Original
  782.     XDAY    ax            ; Extract Day Of Month
  783.     push    ax
  784.     push    2
  785.     push    bx
  786.     call    ConvertWrdToAscii    ; Change to ASCII
  787.     add    bx,ax
  788.     mov    BYTE PTR [bx],'/'
  789.     inc    bx
  790.     XYRS    cx            ; Extract Year From Original
  791.     push    cx
  792.     push    2
  793.     push    bx
  794.     call    ConvertWrdToAscii
  795.  
  796.     mov    bx,dx            ; Restore Structure Pointer
  797.  
  798.     mov    ax,es:[di].TStamp    ; Get Time Stamp From Element
  799.     lea    bx,[bx].TimeStmp    ; Address Screen Time Pointer
  800.     mov    cx,ax            ; Copy Original
  801.     XHRS    ax            ; Extract Hour File Changed
  802.     push    ax
  803.     push    2
  804.     push    bx
  805.     call    ConvertWrdToAscii    ; Change to ASCII
  806.     add    bx,ax
  807.     mov    BYTE PTR [bx],':'    ; Delimit
  808.     inc    bx            ; Next Location
  809.     mov    ax,cx            ; Restore Original
  810.     XMIN    ax            ; Extract Minute Of Hour
  811.     push    ax
  812.     push    2
  813.     push    bx
  814.     call    ConvertWrdToAscii    ; Change to ASCII
  815.     add    bx,ax
  816.     mov    BYTE PTR [bx],':'    ; Delimit
  817.     inc    bx
  818.     XSEC    cx            ; Pull TwoSecs Variable
  819.     push    cx
  820.     push    2
  821.     push    bx
  822.     call    ConvertWrdToAscii    ; Change to ASCII
  823.  
  824.     mov    bx,dx            ; Restore Structure Pointer
  825.  
  826.     mov    ax,WORD PTR es:[di].ByteDesc
  827.     lea    dx,[bx].FSizeB        ; Get File Size Word
  828.     push    ax
  829.     push    5
  830.     push    dx
  831.     call    ConvertWrdToAscii    ; Change To ASCII
  832. ShowLine:
  833.     @VioWrtTTY  ds,bx,SCRNLINE,0    ; Call The Big Guy
  834.     cmp    es:[di].AltFlag,0000h
  835.     jz    RevDone
  836.     mov    es:[di].AltFlag,0000h
  837.     CLRBUFF AltLine         ; Clear Buffer For Screen
  838.     mov    bx,offset AltLine
  839.     push    di
  840.     lea    di,es:[di].AltName
  841.     @FStrMove es,di,ds,bx        ; Get Key Name
  842.     pop    di
  843.     jmp    RevD0
  844. RevDone:
  845.     ret
  846. RevDisplayKey ENDP
  847.  
  848. ConvertWrdToAscii PROC NEAR \
  849.     USES SI CX BX DX, Value:WORD,Cnt:WORD,Area:WORD
  850.     mov    cx,Cnt            ; Load The Conversion Factor
  851.     mov    si,Area         ; And Destination Buffer
  852.     add    si,cx            ; Start At End Of Buffer
  853.     dec    si            ; Pointer Zero Offset
  854.     mov    ax,Value        ; Get The Data Value
  855.     mov    bx,000ah        ; Set Up Divisor
  856. @@:    xor    dx,dx            ; Clear Remainder Register
  857.     div    bx            ; 16 Bit Divide
  858.     add    dx,30h            ; Convert Remainder To ASCII
  859.     mov    BYTE PTR [si],dl    ; Store In Data Buffer
  860.     dec    si            ; Point to next location
  861.     loop    @B            ; All Numbers
  862.     mov    ax,Cnt            ; Return Offset
  863.     ret
  864. ConvertWrdToAscii ENDP
  865.  
  866. RevC_and_D PROC NEAR \
  867.     USES ES DI SI BX,pFileName:WORD
  868.     mov    bx,offset CommandArgv    ; Get String Length
  869.     mov    cx,[bx+2]        ; By Taking Second Args Address
  870.     sub    cx,[bx]         ; And Subtracting First For Difference
  871.     mov    es,CommandSel        ; Address Source
  872.     mov    ax,[bx]
  873.     mov    di,ax
  874.     mov    si,pFileName        ; And Destination Assuming DS is local
  875.     cld
  876.     repe    cmpsb            ; Compare The Strings
  877.     mov    ax,cx            ; Which BURNS the C version
  878.     ret
  879. RevC_and_D ENDP
  880.  
  881. DoWriteData PROC NEAR USES ES DI SI,hfile:WORD, pBuf:FAR PTR,SzBuf:WORD
  882.             LOCAL cbByR:WORD
  883.  
  884.     mov    ax,hfile        ; Handle to file
  885.     mov    cx,SzBuf        ; Size Of Data Buffer
  886.     les    di,pBuf         ; Pointer To Buffer
  887.     push    ax            ; Push Handle
  888.     push    es            ; Pointer To Buffer
  889.     push    di
  890.     push    cx            ; Byte Count To Write From Buffer
  891.     push    ss
  892.     lea    ax,cbByR        ; Push Local Pointer To Count
  893.     push    ax            ; Of bytes actually written
  894.     call    DosWrite
  895.  
  896.     ret
  897. DoWriteData ENDP
  898.  
  899. DoReadData    PROC    NEAR \
  900.         USES ES DI SI, hfile:WORD, pBuf:FAR PTR,SzBuf:WORD
  901.         LOCAL cbByR:WORD
  902.  
  903.     les    di,pBuf         ; Pointer To File Buffer
  904.     lea    si,cbByR        ; Push Bytes Read As Returned by OS/2
  905.     push    hfile            ; File Handle is pushed
  906.     push    es            ; And Buffer Pointer
  907.     push    di
  908.     push    SzBuf            ; How many bytes to read
  909.     push    ss
  910.     push    si
  911.     call    DosRead         ; Call The Big Guy
  912.     mov    ax,cbByR
  913.     ret
  914. DoReadData   ENDP
  915.  
  916. DoOpenFile PROC NEAR \
  917.        USES ES DI SI,OpFlag:WORD,pFileName:FAR PTR,pFileHand:FAR PTR
  918.        LOCAL Action:WORD,ulFileSize:DWORD
  919.     les    di,pFileName        ; Load And Push File Name Pointer
  920.     push    es
  921.     push    di
  922.  
  923.     les    di,pFileHand        ; Load And Push File Handle Pointer
  924.     push    es
  925.     push    di
  926.  
  927.     push    ss            ; Push Pointer To Results Word
  928.     lea    ax,Action
  929.     push    ax
  930.  
  931.     push    0            ; Push Long Zero Length File Size
  932.     push    0
  933.  
  934.     mov    ax,FILE_NORMAL        ; Assume Normal File
  935.     cmp    OpFlag,5
  936.     jnz    @F
  937.     mov    ax,FILE_READONLY    ; Or Only Read From File
  938. @@:    push    ax
  939.     mov    ax,FILE_OPEN        ; Assume Normal Open
  940.     cmp    OpFlag,3
  941.     jnz    @F
  942.     mov    ax,FILE_CREATE        ; Or Else Create New File
  943. @@:    push    ax
  944.     mov    ax,OPEN_ACCESS_READWRITE    ; Assume We Want To Read Or Write
  945.     cmp    OpFlag,5
  946.     jnz    @F
  947.     mov    ax,OPEN_ACCESS_READONLY     ; Or Else We Want To Read Only
  948. @@:    or    ax,OPEN_SHARE_DENYWRITE     ; Combine With Other Process Flag
  949.     push    ax
  950.     push    0            ; OS/2 Reserved Long Value
  951.     push    0            ; Must Be 0
  952.     call    DosOpen         ; Call The Big Guy
  953.  
  954.     or    ax,ax            ; Test Results
  955.     jnz    Done            ; Exit If Error
  956.     cmp    OpFlag,1        ; Test Position For Writing
  957.     jnz    Done            ; So We can Add A New Revision
  958.  
  959.     les    di,pFileHand
  960.     mov    ax,WORD PTR es:[di]    ; Get And Push File Handle
  961.     push    ax
  962.     push    0
  963.     push    0
  964.     push    FILE_END        ; Position At End Of File
  965.     push    ds
  966.     push    offset Newlocation
  967.     call    DosChgFilePtr        ; Call The Big Guy
  968.     xor    ax,ax            ; Resume File Open
  969. Done:
  970.     ret
  971. DoOpenFile    ENDP
  972.  
  973. SpecialSwitch PROC    NEAR    USES BX
  974.  
  975.     mov    bl,BYTE PTR es:[di]    ; Test For Switch Flags as defined
  976.     cmp    bl,'/'            ; Here
  977.     jz    @F
  978.     cmp    bl,'-'            ; or here
  979.     jz    @F
  980.     xor    ax,ax            ; Assume NO FLAG AT ALL
  981.     jmp    short Done
  982. @@:    inc    di            ; Convert To Uppercase to reduce
  983.     mov    bl,BYTE PTR es:[di]    ; number of tests needed
  984.     UPPERCASE  bl
  985. @@:    cmp    bl,'D'            ; Test For Dump Info Flag
  986.     jnz    @F
  987.     mov    ax,DUMPINFO
  988.     jmp    short Done
  989. @@:    mov    ax,LISTINFO        ; Assume List Flag
  990.     cmp    bl,'L'
  991.     jnz    BadS            ; BadSwitch Or Next New Switch
  992.     inc    di            ; Switch good check for options
  993.     mov    bl,BYTE PTR es:[di]    ; such as alternate key listing
  994.     cmp    bl,00h            ; If no flag then end of line
  995.     jz    Done
  996.     UPPERCASE  bl
  997. @@:    cmp    bl,'A'            ; Test For Alternate List
  998.     jnz    Done
  999.     or    ax,LISTALTI        ; Set Flag For Alternate Listing
  1000.     jmp    short Done
  1001. BadS:
  1002.     mov    ax,BADSWITCH        ; Otherwise add more test or return
  1003. Done:                    ; Bad Flag Info
  1004.     ret
  1005. SpecialSwitch endp
  1006.  
  1007. RevGetFileData PROC NEAR USES ES DI,pszFile:FAR PTR
  1008.            LOCAL usSrchCount:WORD
  1009.  
  1010.     mov    usSrchCount,1        ; Single File Search
  1011.     mov    hdir,HDIR_CREATE    ; New Directory Search Handle
  1012.     les    di,pszFile        ; Pointer To String
  1013.  
  1014.     push    es            ; Push Pointer To String
  1015.     push    di
  1016.  
  1017.     push    ds            ; Push Far Pointer To
  1018.     push    offset hdir        ; Directory Search Handle
  1019.     push    FILE_NORMAL        ; Push Attribute Search Condition
  1020.  
  1021.     CALCARRAYOFF    ax,InfoCount,<FILEFINDBUF>
  1022.     mov    bx,ax            ; Get Results
  1023.     lea    ax,fFind[bx]        ; Get Address To File Buffer
  1024.     push    ds            ; Push Far Pointer
  1025.     push    ax            ; To Current FileFindBuffer
  1026.  
  1027.     push    size FILEFINDBUF    ; Push Buffer Size
  1028.  
  1029.     lea    ax,usSrchCount
  1030.     push    ss            ; Push Far Pointer
  1031.     push    ax            ; To Search Results
  1032.  
  1033.     push    0            ; 0L Reserved by OS/2
  1034.     push    0
  1035.     call    DosFindFirst        ; Call OS/2
  1036.     mov    usSrchCount,ax        ; Save Results
  1037.     or    ax,ax
  1038.     jnz    @F            ; If Bad Then So Is Handle
  1039.  
  1040.     push    hdir            ; Push Returned Handle
  1041.     call    DosFindClose        ; Call OS/2
  1042.  
  1043. @@:    inc    InfoCount        ; For Further Array Processing
  1044.     mov    ax,usSrchCount        ; Return Results From Search
  1045.     ret
  1046. RevGetFileData    ENDP
  1047.  
  1048. ArgvArgc PROC NEAR USES ES DI,pArgStr:FAR PTR BYTE,pArgTab:WORD
  1049.     les    di,pArgStr        ; Load Command Line
  1050.     mov    bx,pArgTab
  1051.     mov    CommandArgC,0
  1052. ScanCommand:                ; Scan Command Line From Call
  1053.     cmp    BYTE PTR es:[di],20h    ; Parse The File Name Info
  1054.     jle    @F            ; Found A String Or End Of File
  1055.     inc    di            ; Next Character
  1056.     jmp    short ScanCommand    ; Next Test
  1057.  
  1058. @@:    cmp    WORD PTR es:[di],0000    ; Test End Of Command Line
  1059.     jz    ScanDone        ; End Of Command Line
  1060.     cmp    BYTE PTR es:[di+1],20h    ; Test End Of Command Line
  1061.     jnz    RemoveBlanks
  1062.     inc    di
  1063.  
  1064. RemoveBlanks:                ; First Remove Blanks
  1065.     cmp    BYTE PTR es:[di],20h
  1066.     jnz    @F
  1067.     mov    BYTE PTR es:[di],00h    ; Fill With Zero Terminates
  1068.     inc    di
  1069.     jmp    short RemoveBlanks
  1070.  
  1071. @@:    cmp    BYTE PTR es:[di],00h    ; Make Sure We Are On Letter
  1072.     jg    @F
  1073.     inc    di
  1074. @@:    mov    ax,di            ; Store In Pointer Table
  1075.     mov    [bx],ax         ; The Entire Execution
  1076.     inc    CommandArgC        ; Up The Argc Value
  1077.     add    bx,2            ; Get Next Pointer Offset
  1078.     inc    di            ; Next Character
  1079.     jmp    short ScanCommand    ; Continue Search
  1080.  
  1081. ScanDone:
  1082.     ret
  1083. ArgvArgc    ENDP
  1084.  
  1085. FStrMove PROC NEAR  USES ES DI DS DX SI,pSrc:FAR PTR, pDest:FAR PTR
  1086.     mov    cx,0ffffh        ; Load Infinite Loop
  1087.     les    di,pSrc         ; Point To Source Zero Terminated String
  1088.     mov    dx,di            ; Copy Start Value
  1089.     xor    ax,ax            ; Search for Zero
  1090.     repne scasb            ; Rep While String NE 0
  1091.     sub    di,dx            ; Get String Length
  1092.     mov    cx,di            ; Save In Next counter
  1093.     mov    dx,di            ; Save For Upper Case Conversion
  1094.     les    di,pDest        ; ES DI points to destination
  1095.     lds    si,pSrc         ; DS SI points to Source
  1096.     rep    movsb            ; Move Bytes
  1097.     lds    si,pDest        ; Reload For Near Pointer Access
  1098.     mov    cx,dx            ; Get count again of string
  1099. Fs1:    UPPERCASE <BYTE PTR [si]>    ; Convert To Upper Case
  1100. @@:    inc    si
  1101.     loop    Fs1
  1102.     ret                ; Exit With String Intact
  1103. FStrMove    ENDP
  1104.  
  1105.     END     Revisor
  1106.